<?php
// +---------------+---------------------+------+-----+---------+----------------+
// | Field         | Type                | Null | Key | Default | Extra          |
// +---------------+---------------------+------+-----+---------+----------------+
// | id            | int(11)             | NO   | PRI | NULL    | auto_increment |
// | user_id       | int(11) unsigned    | YES  |     | 0       |                |
// | campaign      | varchar(15)         | YES  |     |         |                |
// | message_type  | varchar(15)         | YES  |     |         |                |
// | mobile        | varchar(11)         | YES  |     |         |                |
// | response_data | text                | YES  |     | NULL    |                |
// | is_response   | tinyint(1)          | YES  |     | 0       |                |
// | user_agent    | varchar(255)        | YES  |     |         |                |
// | request_ip    | bigint(20) unsigned | YES  |     | 0       |                |
// | create_time   | int(11) unsigned    | YES  |     | 0       |                |
// +---------------+---------------------+------+-----+---------+----------------+
namespace app\common\model;

use think\facade\Env;
use think\facade\Config;
use app\common\model\Core;
use app\common\model\User as UserModel;

class SmsLog extends Core
{
    protected $updateTime = NULL;
    protected $auto = [];

    /**
     * 列表搜索方法
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    array              $param     搜索参数
     * @param    integer            $page_rows 每页显示数量
     * @return   Paginate
     */
    public function minePaginate($param, $page_rows = 0)
    {
        if($page_rows < 1){
            $page_rows = Config::get('paginate.list_rows');
        }

        $map = $this->parseSearchParam($param);

        $config = [];
        $config["query"] = $param;
        // 分页参数名是 page ，paginate方法内有获取到该值的方法
        $page = 1;
        if(isset($param["page"])){
            $page = intval($param["page"]);
        }
        $config["page"] = $page;

        $order_type = 'default';
        if(isset($param['order'])){
            $order_type = $param['order'];
        }
        $order_str = $this->queryOrderStr($order_type);
        $paginate = $this->where($map)->order($order_str)->paginate($page_rows, false, $config);
        return $paginate;
    }

    /**
     * 导出申报项目记录
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-21
     * @param    [type]             $param [description]
     * @return   [type]                    [description]
     */
    public function exportExcel($param)
    {
        $date_str = date('Y-m-d', time());
        $objPHPExcel = new \PHPExcel();
        $objPHPExcel->getProperties()
                     ->setCreator('laifuzi') //设置创建者
                     ->setLastModifiedBy($date_str) //设置时间
                     ->setTitle('短信发送日志'); //设置类别

        $activeSheet = $objPHPExcel->getActiveSheet();
        $activeSheet->setTitle("短信发送日志");

        // 设置导出Excel的标题
        $headers = $this->exportHeaders();
        $row_idx = 1;
        foreach ($headers as $col_idx => $header) {
          $activeSheet->setCellValueByColumnAndRow($col_idx, $row_idx, $header['title']);
        }

        $page = 1;
        $per_page = 100; // 每次查询数量
        while(true){
            $param['page'] = $page++;
            $res = $this->minePaginate($param, $per_page);
            $list = $res->all();
            foreach ($list as $key => $item) {
                $row_idx++;
                $col_idx = 0;
                foreach ($headers as $col_idx => $header) {
                    $name = $header['name'];
                    $cell_value = $item[$name];
                    if($cell_value=='' && isset($header['default'])){
                        $cell_value = $header['default'];
                    }
                    switch ($name) {
                        case 'message_type':
                            $cell_value = get_field_text('sms_type', $cell_value);
                            break;
                        case 'is_response':
                            $cell_value = get_field_text('success', $cell_value);
                            break;
                    }
                    $activeSheet->setCellValueByColumnAndRow($col_idx, $row_idx, $cell_value);
                }
            }

            // 已经到最后一页
            if($page >= $res->lastPage()){
                break;
            }
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="sms_log_'.date("mdH").'.xls"');
        header('Cache-Control: max-age=0');
        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
    }

    /**
     * 发送注册短信验证码
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-25
     * @param    [type]             $mobile [description]
     * @return   [type]                     [description]
     */
    public function sendRegisterMessage($mobile){
        $res = ['status' => false, 'data' => [], 'msg' => '发送注册验证码失败'];

        $current_user = login_user();
        if(!empty($current_user)){
            $res['msg'] = '已登录用户不能再注册';
            return $res;
        }

        $valid_fmt = $this->validMobile($mobile);
        if(!$valid_fmt['status']){
            $res['msg'] = $valid_fmt['msg'];
            return $res;
        }

        $UserModel = new UserModel();
        if($UserModel->where('mobile', $mobile)->count()){
            $res['msg'] = '该手机号码已注册，请直接登录';
            return $res;
        }
        return $this->sendAndCreate($mobile, 'register');
    }

    /**
     * 发送重置用户信息验证码
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-27
     * @param    string             $mobile [description]
     * @return   array                      [description]
     */
    public function sendResetInfoMessage($mobile = ''){
        $res = ['status' => false, 'data' => [], 'msg' => '发送重置密码验证码失败'];

        if(empty($mobile)){
            $current_user = login_user();
            if(empty($current_user)){
                $res['msg'] = '请先登录';
                return $res;
            }
            $mobile = $current_user['mobile'];
        }

        $valid_fmt = $this->validMobile($mobile);
        if(!$valid_fmt['status']){
            $res['msg'] = $valid_fmt['msg'];
            return $res;
        }
        $UserModel = new UserModel();
        if(!$UserModel->where('mobile', $mobile)->count()){
            $res['msg'] = '该手机号码未注册';
            return $res;
        }
        return $this->sendAndCreate($mobile, 'reset_info');
    }

    /**
     * 发送修改用户手机号码验证码
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-27
     * @param    string             $mobile [description]
     * @return   array                      [description]
     */
    public function sendChangeMobileMessage($mobile){
        $res = ['status' => false, 'data' => [], 'msg' => '发送修改手机号码验证码失败'];

        $current_user = login_user();
        if(empty($current_user)){
            $res['msg'] = '请先登录';
            return $res;
        }

        $valid_fmt = $this->validMobile($mobile);
        if(!$valid_fmt['status']){
            $res['msg'] = $valid_fmt['msg'];
            return $res;
        }

        $UserModel = new UserModel();
        $old_user = $UserModel->where('mobile', $mobile)->find();
        if(!empty($old_user)){
            if($old_user['id'] == login_user_id()){
                $res['msg'] = '修改的手机号码与您当前登录手机号相同';
                return $res;
            }else{
                $res['msg'] = '该手机号码已被其他用户绑定';
                return $res;
            }
        }

        return $this->sendAndCreate($mobile, 'change_mobile');
    }

    /**
     * 发送验证码
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-25
     * @param    string             $mobile        手机号码
     * @param    string             $message_type 发送的短信类型
     * @param    string             $campaign     活动签名key
     * @return   array
     */
    private function sendAndCreate($mobile, $message_type, $campaign = '')
    {
        $res = ['status' => false, 'data' => [], 'msg' => '发送手机验证码失败'];
        if(empty($campaign)){
            $campaign = Env::get('sms.campaign');
        }

        $req = request();
        $data = [
            'user_id' => login_user_id(),
            'campaign' => $campaign,
            'message_type' => $message_type,
            'mobile' => $mobile,
            'user_agent' => substr($req->header('user-agent'), 0, 200),
            'request_ip' => ip2long($req->ip()),
        ];
        $response_data = $this->sendBySimple($campaign, $mobile);
        $data['response_data'] = $response_data;

        $json_response = json_decode($response_data, 1);
        if($json_response['code'] != '000'){
            $data['is_response'] = false;
            $res['msg'] = $json_response['code'].$json_response['error'];
        }else{
            $res = ['status' => true, 'data' => [], 'msg' => '发送手机验证码成功'];
            $data['is_response'] = true;
        }
        $this->data($data)->allowField(true)->save();
        return $res;
    }

    /**
     * 验证用户填写的验证码是否正确
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-25
     * @param    string             $mobile    手机号码
     * @param    string             $code     用户填写的验证码
     * @return   [type]                       [description]
     */
    public function validSendCode($mobile, $code){
        $res = ['status' => false, 'data' => [], 'msg' => '手机验证码验证失败'];
        $response_data = $this->validBySimple($mobile);

        $json_response = json_decode($response_data, 1);
        if(!is_array($json_response) || !isset($json_response['code'])){
            // 第三方接口请求失败
            $res['msg'] = '手机验证码验证失败';
            return $res;
        }else if($json_response['code'] != '000'){
            $res['msg'] = $json_response['error'];
            return $res;
        }

        if(isset($json_response['result']) && isset($json_response['result']['code'])){
            $valid_code = $json_response['result']['code'];
        }else{
            $valid_code = 'error';
        }
        if($code != $valid_code){
            $res['msg'] = '您输入的手机验证码不正确或已过期';
        }else{
            $res = ['status' => true, 'data' => [], 'msg' => '手机验证码验证成功'];
        }
        return $res;
    }

    /**
     * 测试发送短信方法
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-27
     * @param    [type]             $mobile [description]
     * @return   [type]                     [description]
     */
    public function testSendBySimple($mobile = ''){
        $campaign = Env::get('sms.campaign');
        if(empty($mobile)){
            $mobile = Env::get('sms.test_mobile');
        }
        $response_data = $this->sendBySimple($campaign, $mobile);
        $json_response = json_decode($response_data, 1);
        if(is_array($json_response)){
            return $json_response;
        }
        $res = ['response_data' => $response_data];
        return $res;
    }

    /**
     * 测试验证短信方法
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-27
     * @param    [type]             $mobile [description]
     * @return   [type]                     [description]
     */
    public function testValidBySimple($mobile = ''){
        if(empty($mobile)){
            $mobile = Env::get('sms.test_mobile');
        }
        $response_data = $this->validBySimple($mobile);
        $json_response = json_decode($response_data, 1);
        if(is_array($json_response)){
            return $json_response;
        }
        $res = ['response_data' => $response_data];
        return $res;
    }

    /**
     * 使用Simple通道发送短信
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-25
     * @param    string             $type  签名类型
     * @param    string             $mobile 手机号码
     * @return   text
     */
    private function sendBySimple($type, $mobile){
        $env = Env::get('app.environment', 'production');
        // 只有在production环境时才调用第三方平台接口
        if($env != 'production'){
            $data = [
                'code' => '000',
                'msg' => 'success',
                'error' => false,
                'result' => [],
            ];

            // $data = [
            //     'code' => '002',
            //     'msg' => '手机号 格式不正确。',
            //     'error' => true,
            //     'result' => [],
            // ];
            return json_encode($data);
        }

        $host = Env::get('sms.host');
        $url = $host.'/pci/send-phone-code';
        $post_data = [
            'type' => $type,
            'phone' => $mobile,
        ];
        return http_post($url, $post_data);
    }

    /**
     * 使用Simple通道验证用户输入的短信验证码
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-25
     * @param    string             $mobile [description]
     * @return   text
     */
    private function validBySimple($mobile){
        $env = Config::get('app.environment');
        // 只有在production环境时才调用第三方平台接口
        if($env != 'production'){
            $data = [
                'code' => '000',
                'msg' => 'success',
                'result' => ['code' => '123456'],
                'error' => false,
            ];

            // $data = [
            //     'code' => '001',
            //     'msg' => '验证码不存在或已过期!',
            //     'result' => [],
            //     'error' => true,
            // ];
            return json_encode($data);
        }

        $host = Env::get('sms.host');
        $url = $host.'/pci/get-phone-code';
        $post_data = [
            'phone' => $mobile,
        ];
        return http_post($url, $post_data);
    }

    /**
     * 转化查询条件
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    array              $param [description]
     * @return   array                     [description]
     */
    private function parseSearchParam($param)
    {
        $map = [];
        foreach ($param as $key => $value) {
            if(!is_array($value)){
                $value = trim($value);
            }
            switch ($key) {
            case "message_type":
                if(!empty($value)){
                    $map[] = [$key, '=', $value];
                }
                break;
            case "is_response":
                if($value !=''){
                    $map[] = [$key, '=', boolval($value)];
                }
                break;
            case "keyword":
                if(empty($value)){
                    continue;
                }else{
                    $keyword = "%{$value}%";
                }
                $map[] = ["mobile", "like", $keyword];
                break;
            }
        }
        return $map;
    }

    /**
     * 搜索排序方式
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    string             $param 排序方式
     * @return   string                    [description]
     */
    protected function queryOrderStr($order_type = '')
    {
        return 'id DESC';
    }

    /**
     * 导出字段列表
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-21
     * @return   [type]             [description]
     */
    private function exportHeaders(){
        return [
            ['name' => 'id', 'title' => 'ID', 'type' => 'string', 'default' => ''],
            ['name' => 'mobile', 'title' => '手机号码', 'type' => 'string', 'default' => ''],
            ['name' => 'message_type', 'title' => '短信类型', 'type' => 'string', 'default' => ''],
            ['name' => 'is_response', 'title' => '发送是否成功', 'type' => 'string', 'default' => '0'],
            ['name' => 'create_time', 'title' => '发送时间', 'type' => 'date', 'default' => ''],
        ];
    }
}
